package ServerTest;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collection;
import java.util.Map;

public class ServerReaderThread extends Thread{
    private Socket socket;
    public ServerReaderThread(Socket socket)
    {
        this.socket = socket;
    }
    @Override
    public void run()
    {
        //开发服务端实现方法
        //1.获取客户端输入流
        try {
            DataInputStream dis = new DataInputStream(socket.getInputStream());
            //客户端的信息包括1.登录信息，2.群发消息，3.私聊消息
            while(true){
                int type = dis.readInt();
                switch (type) {
                case ConstantServer.LOGIN:
                    //登录信息
                    //获取昵称，并且更新当前用户列表
                    String nickname = dis.readUTF();
                    Server.userMap.put(socket, nickname);
                    updateUserList();
                    break;
                case ConstantServer.GROUP_MESSAGE:
                    //群发消息
                    String msg = dis.readUTF();
                    String name = Server.userMap.get(socket);
                    //设置群发消息方法
                    groupMessage(msg,name);
                    break;
                case ConstantServer.PRIVATE_MESSAGE:
                    //私聊消息
                    String toName = dis.readUTF();
                    String toMsg = dis.readUTF();
                    privateMessage(toName,toMsg);
                }
            }

        } catch (Exception e) {
            System.out.println("客户端下线:"+socket.getInetAddress().getHostAddress());
            Server.userMap.remove(socket);
            updateUserList();
        }
    }

    private void privateMessage(String toName, String toMsg) {
        //将私聊信息先进行封装，再发送给指定客户端的socket管道
        StringBuilder sb = new StringBuilder();
        String name = Server.userMap.get(socket);
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss EEE a");
        sb.append(name).append(" ").append(df.format(now)).append("\r\n").append(toMsg).append("\r\n");

        //如果对方不在线，则向发送消息的客户端发送一个提示信息
        if(!Server.userMap.containsValue(toName)){
            try {
                DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
                dos.writeInt(ConstantServer.PRIVATE_MESSAGE);
                dos.writeUTF("----对方不在线，请稍后再试----");
                return;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        for(Socket socket:Server.userMap.keySet()){
            try {
                DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
                if(Server.userMap.get(socket).equals(toName)){
                    dos.writeInt(ConstantServer.PRIVATE_MESSAGE);
                    dos.writeUTF(sb.toString());
                    dos.flush();
                    break;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }


    }

    private void groupMessage(String msg,String name) {
        //将群发消息转发给所有在线客户端Socket管道
        //封装消息
        StringBuilder sb = new StringBuilder();
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss EEE a");
        sb.append(name).append(" ").append(df.format(now)).append("\r\n").append(msg).append("\r\n");

        for (Socket socket:Server.userMap.keySet()) {
            try {
                DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
                dos.writeInt(ConstantServer.GROUP_MESSAGE);
                dos.writeUTF(sb.toString());
                dos.flush();//及时刷新
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private void updateUserList() {
        //更新在线用户列表
        //拿到所有在线客户端用户名称，将这些数据转发给全部在线客户端Socket管道
        Collection<String> users = Server.userMap.values();
        for (Socket socket:Server.userMap.keySet()) {
            try {
                DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
                dos.writeInt(ConstantServer.LOGIN);
                dos.writeInt(users.size());
                for(String user:users){
                    dos.writeUTF(user);
                }
                dos.flush();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}
